#include "SerialGUI.h"
#include "configdialog.h"

#include <QDebug>
#include <QCoreApplication>

SerialGUI::SerialGUI(QSerialPort *parent) :
    QSerialPort(parent)
{
    configValid = false;
}

void SerialGUI::readLastConfig(void)
{
    //ConfigDialog diag(qApp->applicationName(),this->objectName());
    ConfigDialog diag;
    if(diag.readConfig())   //config ini file is valid
        applyConfig(diag.configValid,diag.port,diag.mode);
    //else: do not change
}

void SerialGUI::execConfigDialog(void)
{
    //ConfigDialog diag(qApp->applicationName(),this->objectName());
    ConfigDialog diag;
    diag.exec();
    applyConfig(diag.configValid,diag.port,diag.mode);
}

bool SerialGUI::testConfig(QString _port,QString _mode)
{
    bool isValid = true;

    //qDebug() << _port;
    //qDebug() << _mode;

    if(_port == QString::null)
        return false;

    _mode.toUpper();

    QStringList args = _mode.split(',');

    if(args.count() != 4)
        return false;

    QSerialPort::DataBits _databits;
    switch(args.at(1).toInt())
    {
        case 5:
            _databits = QSerialPort::Data5;
            break;
        case 6:
            _databits = QSerialPort::Data6;
            break;
        case 7:
            _databits = QSerialPort::Data7;
            break;
        case 8:
            _databits = QSerialPort::Data8;
            break;
        default:
            return false;
    }

    QSerialPort::Parity _parity;
    if(args.at(2) == QString("N"))
        _parity = QSerialPort::NoParity;
    else if(args.at(2) == QString("E"))
        _parity = QSerialPort::EvenParity;
    else if(args.at(2) == QString('O'))
        _parity = QSerialPort::OddParity;
    else
        return false;

    QSerialPort::StopBits _stopbits;
    if(args.at(3) == QString("1"))
        _stopbits = QSerialPort::OneStop;
    else if(args.at(3) == QString("1.5"))
        _stopbits = QSerialPort::OneAndHalfStop;
    else if(args.at(3) == QString("2"))
        _stopbits = QSerialPort::TwoStop;
    else
        return false;

    if(!QSerialPortInfo(_port).isValid())
        return false;

    quint32 _baudrate = args.at(0).toLong(&isValid);
    if(!isValid)
        return false;

    isValid = false;
    foreach(const quint32 &_bb,QSerialPortInfo::standardBaudRates())
    {
        if(_bb == _baudrate)
            isValid = true;
    }
    if(!isValid)
        return false;

    return true;
}

void SerialGUI::applyConfig(bool isValid,QString _port,QString _mode)
//only apply tested config
{
    configValid = isValid;
    modeString = _mode;

    if(isValid)
    {

    setPort(_port);

    _mode.toUpper();
    QStringList args = _mode.split(',',QString::KeepEmptyParts);
    setBaudRate(args.at(0).toLong());
    switch(args.at(1).toInt())
    {
        case 5:
            setDataBits(QSerialPort::Data5);
            break;
        case 6:
            setDataBits(QSerialPort::Data6);
            break;
        case 7:
            setDataBits(QSerialPort::Data7);
            break;
        case 8:
            setDataBits(QSerialPort::Data8);
            break;
        default:
            return;
    }

    if(args.at(2) == QString("N"))
        setParity(QSerialPort::NoParity);
    else if(args.at(2) == QString("E"))
        setParity(QSerialPort::EvenParity);
    else if(args.at(2) == QString('O'))
        setParity(QSerialPort::OddParity);
    else
        return;

    if(args.at(3) == QString("1"))
        setStopBits(QSerialPort::OneStop);
    else if(args.at(3) == QString("1.5"))
        setStopBits(QSerialPort::OneAndHalfStop);
    else if(args.at(3) == QString("2"))
        setStopBits(QSerialPort::TwoStop);
    else
        return;
    }

    emit configValidChanged(configValid);
}

void SerialGUI::setConfigValid(bool isValid)
{
    configValid = isValid;
    emit configValidChanged(isValid);
}

void SerialGUI::canReadLine()
{
    emit hasNewLine();
}
